﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WWWSiteHelper
{
    public class TagAttributeValueKnowledge
    {
        public class FilledTag
        {
            public FilledTag(string tag, IList<KeyValuePair<string, string>> attributeToValue)
            {
                this.Tag = tag;
                this.AttributeToValue = attributeToValue;
            }

            public IList<KeyValuePair<string, string>> AttributeToValue { get; protected set; }
            public string Tag { get; protected set; }
        }

        public class GiveBackFunctionProvider
        {
            private IList<FilledTag> essentialKnowledge = new List<FilledTag>();
            private string lastTag = null, lastAttribute = null;
            private IList<KeyValuePair<string, string>> tagList = null;

            public void GiveBack(HTMLParserState prevState, HTMLParserState state, String token)
            {
                if (prevState == HTMLParserState.TagName)
                {
                    //System.Console.WriteLine("giveback tag " + lastTag);
                    lastTag = token;
                    tagList = new List<KeyValuePair<string, string>>();
                    essentialKnowledge.Add(new FilledTag(lastTag, tagList));
                }
                else if (prevState == HTMLParserState.AttributeName)
                {
                    lastAttribute = token;
                    tagList.Add(new KeyValuePair<string, string>(lastAttribute, ""));
                }
                else if (prevState == HTMLParserState.AttributeValue || prevState == HTMLParserState.AttributeValueWithoutQuote)
                {
                    tagList.RemoveAt(tagList.Count - 1);
                    tagList.Add(new KeyValuePair<string, string>(lastAttribute, token));
                }
            }

            public IList<FilledTag> getEssentialKnowledge()
            {
                return essentialKnowledge;
            }
        }

        private IList<FilledTag> tags;

        public TagAttributeValueKnowledge(IList<FilledTag> tags)
        {
            this.tags = tags;
        }

        public static TagAttributeValueKnowledge parse(string content)
        {
            HTMLParserState startState = HTMLParserState.Text;
            List<HTMLParserState> acceptingStates = new List<HTMLParserState>();
            acceptingStates.Add(HTMLParserState.Text);
            GiveBackFunctionProvider giveBackProvider = new GiveBackFunctionProvider();
            StackBehaviorProvider<HTMLParserState> behaviorProvider
                = new StackBehaviorProvider<HTMLParserState>(new SortedSet<HTMLParserState>(new HTMLParserState[]{
                    HTMLParserState.TagName,
                    HTMLParserState.AttributeName,
                    HTMLParserState.AttributeValue,
                    HTMLParserState.AttributeValueWithoutQuote}));
            AutomatonWithStack<HTMLParserState> automaton
                = new AutomatonWithStack<HTMLParserState>(
                    startState,
                    acceptingStates,
                    HTMLStateTransition.Transition,
                    giveBackProvider.GiveBack,
                    behaviorProvider.DefaultBehavior);
            automaton.Execute(content);
            //System.Console.WriteLine(String.Join(", ", giveBackProvider.getEssentialKnowledge()));
            return new TagAttributeValueKnowledge(giveBackProvider.getEssentialKnowledge());
        }

        public IList<FilledTag> getAll()
        {
            return tags;
        }
    }
}
